home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / SeqPups / appsrc / ChildApp.c
C/C++ Source or Header  |  1996-07-05  |  9KB  |  324 lines

  1. /* ChildApp.c
  2.      d.g.gilbert, Dec'94
  3.      
  4.    program main call for Mac apps needing to handle command-line parameters
  5.    true main should be renamed to
  6.        void RealMain(int argc, char** argv);
  7.    used HighLevel event called "Cmdl" that calling application sends to this
  8.    child application.  This isn't an appleevent.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15.  
  16. #undef DEBUG
  17.  
  18. /* use this only w/ Mac apps */
  19. #define MACINTOSH 1
  20. #include <EPPC.h> /* Apple highlevel events */
  21. #include <quickdraw.h> 
  22. #include <dialogs.h> 
  23.  
  24. void  BeFriendly();   // use for multiprocessing
  25. Boolean StopKey();        // check if user wants to quit in middle
  26.  
  27. extern "C" int RealMain( int argc, char *argv[]);
  28. extern "C" int ccommand(char **argv[]);
  29.  
  30. #ifdef DEBUG
  31. char* long2str( long val)
  32. {
  33.     static char buf[5];
  34.   buf[0]= (val >> 24) & 0xff;
  35.   buf[1]= (val >> 16) & 0xff;
  36.   buf[2]= (val >> 8) & 0xff;
  37.   buf[3]= val & 0xff;
  38.   buf[4]= 0;
  39.     return buf;    
  40. }
  41. #endif
  42.  
  43. char* FindWordEnd( char** start)
  44. {
  45.     char *ep, *cp;
  46.     ep= cp= *start;
  47.     if (*cp == '"' || *cp == '\'') { 
  48.         char key= *cp;
  49.         cp++; 
  50.         (*start)++; // need to move word start up 1
  51.         for (ep= cp; *ep && *ep != key; ep++) ; 
  52.         }
  53.     else if (*cp) { 
  54.         for (ep= cp+1; 
  55.             *ep && *ep>' ' && *ep!='>' && *ep!='<' && *ep != '"' && *ep != '\''; 
  56.             ep++) ; 
  57.         }
  58.     return ep;
  59. }   
  60.  
  61. char* FindWordStart( char* cp)
  62. {
  63.     while (*cp && *cp <= ' ') cp++;
  64.     return cp;
  65. }
  66.  
  67.  
  68. main(int argc, char *argv[])
  69. {
  70.     enum { kMaxBuflen = 512 };
  71.     Boolean    doloop = true, flag;
  72.     char     **myargv, * cmdline;
  73.     int        i, err, trynum, myargc = argc;    
  74.     long    time;
  75.     unsigned long msgRefcon, buflen;
  76.     EventRecord evt;
  77.     TargetID    sender;
  78.  
  79.         // need this to prevent crashes
  80.     MaxApplZone();
  81.     InitGraf((Ptr)&qd.thePort);
  82.     InitFonts();
  83.     InitWindows();
  84.     InitMenus();
  85.     TEInit();
  86.     InitDialogs(nil);
  87.     InitCursor();
  88.  
  89. #ifdef DEBUG
  90.   freopen( "ChildApp.stdout", "w", stdout);  
  91.   fprintf(stdout, "+debug: Test output from ChildApp.c --\n+debug: where is stdout going to??\n");
  92. #endif
  93.  
  94.     trynum= 0;
  95.     buflen= kMaxBuflen;
  96.     cmdline= (char*) malloc(buflen+1);
  97.     memset(cmdline,0,buflen+1);
  98.     while (WaitNextEvent( highLevelEventMask, &evt, 2, NULL) || trynum<3)  { 
  99.         trynum++;    
  100.         err= AcceptHighLevelEvent( &sender, &msgRefcon, cmdline, &buflen);
  101.  
  102. #ifdef NOT_DEBUG
  103.         fprintf(stderr, " HL Event '%s' ", long2str(evt.message));
  104.         fprintf(stderr, " HL message '%s' ", long2str(msgRefcon));
  105.         fprintf(stderr, " error= %d \n", err);
  106. #endif    
  107.     
  108.     if (msgRefcon == 'Cmdl') {
  109.         if (err == bufferIsSmall) {
  110.             free(cmdline);
  111.             buflen= kMaxBuflen;
  112.             cmdline= (char*) malloc( buflen+1);
  113.             err= AcceptHighLevelEvent( &sender, &msgRefcon, cmdline, &buflen);
  114.             }
  115.             
  116.         if (!err) {
  117.             /* push buf into argv, separating words */
  118.         char  *cp, *ep, *sin, *sout, *serr, * maxp, savec;
  119.         char  done, nextStderr, nextStdin, nextStdout;
  120.  
  121.         if (buflen>kMaxBuflen) buflen= kMaxBuflen;
  122.         cmdline[buflen]= 0;        
  123.         sout= sin= serr= NULL;
  124.         nextStderr= nextStdin = nextStdout= 0;
  125.         done= 0;
  126.         myargc= 0;
  127.         myargv= (char**) malloc(  (myargc+2) * sizeof(char*));
  128.         cp= cmdline; 
  129.         maxp= cmdline + buflen;
  130.         
  131.             {
  132.             enum { kDlogID = 100 };
  133.             WindowPtr wPort;
  134.             char buf[kMaxBuflen];
  135.             CursHandle hCurs;
  136.             
  137.             memset(buf,0,kMaxBuflen);
  138.             sprintf( buf, "Running %s ...", cmdline);
  139.             paramtext( buf, "1", "2", "3");
  140.             wPort= GetNewDialog( kDlogID, NULL, (GrafPtr)-1);
  141.             if (wPort) DrawDialog( wPort);
  142.             hCurs = GetCursor(watchCursor);
  143.           if (hCurs) SetCursor(*hCurs);
  144.             }
  145.  
  146. #ifdef DEBUG 
  147. fprintf(stderr, " Cmdline: '%s' \n", cmdline);
  148. #endif
  149.         while (!done && cp<maxp) {
  150.             cp= FindWordStart( cp);
  151.                 ep= FindWordEnd( &cp);
  152.                 
  153. #ifdef DEBUG
  154. savec= *ep; *ep= 0; 
  155. fprintf(stderr, " +cmdline word: '%s' \n", cp);
  156. *ep= savec;
  157. #endif
  158.                 if (nextStderr) {
  159.                     nextStderr= 0;
  160.                     serr= cp;
  161.                     if (*ep) *ep= 0; else done= 1;
  162.                     }
  163.                 else if (nextStdout) {
  164.                     nextStdout= 0;
  165.                     sout= cp;
  166.                     if (*ep) *ep= 0; else done= 1;
  167.                     }
  168.                 else if (nextStdin) {
  169.                     nextStdin= 0;
  170.                     sin= cp;
  171.                     if (*ep) *ep= 0; else done= 1;
  172.                     }
  173.                 else if (*cp == '2' && cp[1] == '>') {
  174.                     nextStderr= 1;
  175.                     ep= cp+1;
  176.                     }
  177.            else if (*cp == '>') {
  178.                     nextStdout= 1;
  179.                     ep= cp;
  180.                }
  181.            else if (*cp == '<') {
  182.                     nextStdin= 1;
  183.                     ep= cp;
  184.                }
  185.            else {
  186.                     if (*ep) *ep= 0; else done= 1;
  187.                     if (*cp) {
  188.                         myargc++;
  189.                         myargv= (char**) realloc(myargv, (myargc+2) * sizeof(char*));
  190.                         myargv[myargc-1]= cp;
  191.                         }
  192.                     }
  193.                 cp= ep+1;
  194.                 }
  195.         myargv[myargc]= NULL;
  196.  
  197. #ifdef DEBUG
  198. fprintf(stderr, " +comment: stderr '%s' \n", serr);
  199. if (sout) fprintf(stderr, "+comment: new stdout is '%s'\n",sout);
  200. if (serr) fprintf(stderr, "+comment: new stderr is '%s'\n",serr);
  201. if (sin) fprintf(stderr, "+comment: new stdin is '%s'\n",sin);
  202. for (i=0; i<myargc; i++) fprintf(stderr, "arg[%d]= '%s'\n", i, myargv[i]);
  203. #endif
  204.         if (sin) freopen( sin, "r", stdin);
  205.         if (serr) freopen( serr, "a", stderr);  
  206.             if (sout) freopen( sout, "a", stdout);  //where oh where is stdout going !????
  207.                 
  208.             
  209.             err= RealMain(myargc, myargv);
  210.  
  211. #ifdef DEBUG
  212. fprintf(stdout, "+debug: Test stdout from ChildApp.c --\n+debug: where is stdout going to??\n");
  213. fprintf(stderr, "+error: Test stderr from ChildApp.c --\n+error: where is stderr going to??\n");
  214. #endif
  215.             //fflush(stdout);
  216.             //fclose(stdout); //??
  217.             exit(0);   
  218.             }
  219.         exit(0);  
  220.         }
  221.     }
  222.  
  223.     do {
  224.       myargc = ccommand( &myargv);
  225.         err= RealMain( myargc, myargv);
  226.         fflush(stdout);
  227.         } while (doloop);
  228. }
  229.  
  230.  
  231.  
  232. Boolean StopKey()
  233. {    
  234. EventRecord    ev;
  235.  
  236.     if (EventAvail( keyDownMask+autoKeyMask, &ev)) {
  237.       if (  (ev.modifiers & cmdKey)  
  238.        && ((char)(ev.message & charCodeMask) == '.') ) {
  239.             SysBeep(1);
  240.           (void) GetNextEvent( keyDownMask+autoKeyMask, &ev);
  241.           return true;
  242.           }
  243.       }
  244.     return false;
  245. }
  246.  
  247. Boolean Keypress()
  248. {    EventRecord    ev;
  249.     return EventAvail( keyDownMask+keyUpMask+autoKeyMask, &ev);
  250. }
  251.  
  252. /******
  253. From dowdy@apple.com Wed Sep  4 21:06:10 1991
  254. Received: from apple.com by sunflower.bio.indiana.edu
  255.         (4.1/9.5jsm) id AA04821; Wed, 4 Sep 91 21:06:08 EST
  256. Received: from [90.10.20.25] by apple.com with SMTP (5.61/25-eef)
  257.         id AA07198; Wed, 4 Sep 91 19:06:53 -0700
  258.         for gilbertd@sunflower.bio.indiana.edu
  259. Date: Wed, 4 Sep 91 19:06:53 -0700
  260. Message-Id: <9109050206.AA07198@apple.com>
  261. From: dowdy@apple.com (Tom Dowdy)
  262. To: gilbertd@sunflower.bio.indiana.edu
  263. Subject: Re: MPW SIOW library
  264. References: <1991Sep1.174155.13408@gn.ecn.purdue.edu> <6260@dftsrv.gsfc.nasa.gov
  265. > <1991Sep4.233506.25878@bronze.ucs.indiana.edu>
  266. Organization: Apple Computer, Inc.
  267. Status: R
  268.  
  269. In article <1991Sep4.233506.25878@bronze.ucs.indiana.edu>, gilbertd@sunflower.bi
  270. o.indiana.edu (Don Gilbert) writes:
  271. > In article <6260@dftsrv.gsfc.nasa.gov> rdominy@kong.gsfc.nasa.gov (Robert Domi
  272. ny) writes:
  273. > >
  274. > >I have tried calling the routine EventAvail from an SIOW application to
  275. > >provide background processing time without success.  I suspect you
  276. >
  277. > I just put a commandline c program into SIOW and sprinkled some calls
  278. > to WaitNextEvent thru the time consuming procedures.  It seems to work
  279. > okay, though a bit cranky, for getting the app to work in the background.
  280. > When I say cranky, it will miss some os events telling it to shift into
  281. > background, but if I beat the mouse on the desktop, it will eventually
  282. > shift into background.
  283.  
  284. This is just a guess, but the process manager will continue to call
  285. you with update events if you fail to handle them.  After you have
  286. ignore something like 120 requests to update a window of yours,
  287. the PM will assume you are a "MultiFinder hostile" application
  288. and stop giving them to you until the update rgn changes.
  289.  
  290. I'm wondering if this is causing your initial strangeness.  I know
  291. a fellow programmer here got himself into the same fix and
  292. this ended up being the reason he saw his application perform so slowly
  293. in the background.  Once the events were cleared, things were fine again.
  294.  
  295.  Tom Dowdy                 Internet:  dowdy@apple.COM
  296.  Apple Computer MS:81EQ    UUCP:      {sun,voder,amdahl,decwrl}!apple!dowdy
  297.  20525 Mariani Ave         AppleLink: DOWDY1
  298.  Cupertino, CA 95014
  299.  "The 'Ooh-Ah' Bird is so called because it lays square eggs."
  300. ***************/                                                                  
  301.                                                                                                                                 
  302. void  BeFriendly(void)
  303. /* make this app multifinder-friendly w/ background processing */
  304. /* this can slow the app down quite a bit -- don't use too liberally */
  305. {
  306.     const int cmdKey = 256;  /* command-period == halt */
  307.     const long charCodeMask = 0x000000FF;
  308.     int    eventMask = osMask; /*? +keyDownMask+highLevelEventMask*/
  309.     long    sleepTime    = 1; /* # x 1/60 to sleep for others */
  310.     EventRecord    theEvent;
  311.     
  312.     if (WaitNextEvent( eventMask,    &theEvent, sleepTime, NULL)) {  
  313.     /*****
  314.         if (theEvent.what==keyDown) { 
  315.             if ((theEvent.message & charCodeMask == '.') 
  316.                 && (theEvent.modifiers & cmdKey !=0)) 
  317.                     exit(1); 
  318.             }
  319.         ******/
  320.         }
  321.     /* SpinCursor(1); */ /* !!!? not seeing this, need .rsrc ACUR cursor ? */ 
  322. }
  323.  
  324.